using System;
using System.Collections;
using System.Data;
using FrameworkQ.ObjectSpace.Data.Providers;

namespace FrameworkQ.ObjectSpace
{
	/// <summary>
	/// Represents a connection to database
	/// </summary>
	public class DatabaseConnection
	{
		private string _connectionString= "";
		private IDbConnection _connection = null;
        private IDatabaseProvider _provider = null;

		/// <summary>
		/// Creates a database connection obejct with a connection string and 
		/// a database connection.
		/// </summary>
		/// <param name="connectionString"></param>
		public DatabaseConnection (IDatabaseProvider provider, string connectionString)
		{
			_connectionString = connectionString;
            _provider = provider;
			_connection = DBObjectsFactory.CreateConnection (provider, connectionString);
		}

		/// <summary>
		/// The actual connection obejct to be used for communication
		/// with the database.
		/// </summary>
		public IDbConnection Open()
		{
			if (_connection.State == ConnectionState.Closed)
			{
				_connection.Open();
			}
			return _connection;
		}

		public void Close ()
		{
			if (_transaction==null)
			{
				_connection.Close();
			}
		}

		public IDbCommand GetCommand (string commandText)
		{
			IDbConnection conn = Open();
			IDbCommand cmd = DBObjectsFactory.CreateCommand(_provider,  commandText,conn,Transaction);
			return cmd;
		}

		public IDbTransaction BeginTransaction (IsolationLevel level)
		{
			if(	_connection.State == ConnectionState.Closed )
			{
				_connection.Open();
			}
			if (_transaction!=null)
			{
				throw new InvalidOperationException ("Only one transaction supported per connection");
			}
			IDbTransaction tran = _connection.BeginTransaction (level);
			_transaction = tran;
			return tran;
		}

		public void EndTransaction()
		{
			if (_transaction==null)
			{
				throw new InvalidOperationException ("Must have and open transaction to end");
			}
			else
			{
				_transaction = null;
			}
		}

		/// <summary>
		/// Connection string to the database
		/// </summary>
		public string Connectionstring
		{
			get{return _connectionString;}
			set{_connectionString=value;}			
		}

		private IDbTransaction _transaction = null;

		/// <summary>
		/// Transaction to be associated with the connection
		/// </summary>
		public IDbTransaction Transaction
		{
			get{return _transaction;}
		}


        /// <summary>
        /// Transaction to be associated with the connection
        /// </summary>
        public IDatabaseProvider Provider
        {
            get { return _provider; }
        }

	}
}
